package com.wnxy.sddfp.access.service.impl;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wnxy.sddfp.access.entity.BankRespDto;
import com.wnxy.sddfp.access.entity.TradeLog;
import com.wnxy.sddfp.access.mapper.TradeLogMapper;
import com.wnxy.sddfp.access.service.ITradeLogService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wnxy.sddfp.common.model.BaseResult;
import com.wnxy.sddfp.common.model.dto.bank.BankCardAddDTO;
import com.wnxy.sddfp.common.model.dto.bank.SignatureDto;
import com.wnxy.sddfp.common.model.vo.borrow.BorrowSyncRecordVo;
import com.wnxy.sddfp.common.utils.EncryptUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

/**
 * <p>
 * 托管系统交易记录表 服务实现类
 * </p>
 *
 * @author yellow docker
 * @since 2024-04-16
 */
@Slf4j
@Service
public class TradeLogServiceImpl extends ServiceImpl<TradeLogMapper, TradeLog> implements ITradeLogService {

    @Autowired
    private RestTemplate restTemplate;

    @Override
    public SignatureDto proxyBindCardLog(BankCardAddDTO bankCardAddDTO) throws JsonProcessingException {

        //01 日志记录
        TradeLog tradeLog = new TradeLog();

        //请求码
        tradeLog.setReqCode(bankCardAddDTO.getReqCode());
        // 绑卡字符串
        tradeLog.setReqType("USER_BIND_CARD");
        //操作主体  具体的用户操作
        tradeLog.setObjectId(bankCardAddDTO.getUserId());
        //创建时间
        tradeLog.setCreateDate(LocalDateTime.now());
        //数据是否同步 (银行你请求数据后 银行会给你回复 需要同步) 0
        tradeLog.setSynchronizeStatus(0);
        // 确认时间 银行返回数据的同步时间
        tradeLog.setConfirmDate(LocalDateTime.now());
        //银行给你返回的数据   没有访问银行 给默认数据
        tradeLog.setResponseData("");

       //开启一个线程 在子线程中存储日志
//        new Thread(()->{
//            save(tradeLog);
//        }).start();

        //创建 一个线程池 存储数据
        // 1、创建线程池   2、线程中执行任务   3、关闭线程池(释放资源)
        //创建一个单例的线程池  只有一个线程的线程池
        ExecutorService executorService = Executors.newSingleThreadExecutor();

        //执行线程任务
        executorService.execute(()->{
            save(tradeLog);
        });  //线程直接执行完结束
        //executorService.submit();  //线程有返回值

        executorService.shutdown();  //关闭线程

        //02 银行访问   (银行系统不需要我们自己开发 都是现成的 中国银行、平安银行)
        // 发送请求访问 银行
        //银行返回的数据  这里我就直接new
        SignatureDto signatureDto = new SignatureDto();
        signatureDto.setBankUrl("http://localhost:5600/bank/user");
        signatureDto.setPlatformNo("SDDFQ");
        //  请求数据
        signatureDto.setReqData(new ObjectMapper().writeValueAsString(bankCardAddDTO));
        signatureDto.setReqCode(bankCardAddDTO.getReqCode());

        return signatureDto;
    }

    /**
     * 请求借款的时候、把借款记录同步到  bank-sys系统中
     * @param borrowSyncRecordVo
     * @return
     */
    @Override
    public BaseResult syncBorrowRecord(BorrowSyncRecordVo borrowSyncRecordVo) {

        //01 日志记录
        TradeLog tradeLog = new TradeLog();
        //借款请求码
        tradeLog.setReqCode(borrowSyncRecordVo.getReqCode());
        //请求类型   银行系统中创建 CREATE 借款记录
        tradeLog.setReqType("CREATE");
        //主题  userId
        tradeLog.setObjectId(borrowSyncRecordVo.getUserId());
        //创建时间
        tradeLog.setCreateDate(LocalDateTime.now());

        // 默认是0  未 同步  (银行系统返回数据这里需要更新为 1)
        //tradeLog.setSynchronizeStatus(0);
        // (银行系统返回数据这里需要更新为 )
        tradeLog.setConfirmDate(LocalDateTime.now());
        // (银行系统返回数据这里需要更新为 )
        //tradeLog.setResponseData("");

        save(tradeLog);

        //02 访问 银行系统 (同步数据到银行系统)
        // url  参数
        String url = "http://localhost:5600/service?serviceName=SYNC_BORROW_RECORD&reqData=";
        //参数  k-v 他们的要求来
        // http://localhost:5600/service?serviceName=SYNC_BORROW_RECORD&reqData=xx
        String jsonString = JSON.toJSONString(borrowSyncRecordVo);
        //加密
        String reqData = EncryptUtil.encodeUTF8StringBase64(jsonString);
        //转成Url编码
        String reqDataUrl = EncryptUtil.encodeURL(reqData);
        url = url + reqDataUrl;
        log.info("发送银行系统的url===>{}",url);
        //发送 数据 到银行系统
        String respBody= restTemplate.getForObject(url, String.class);
        log.info("银行系统给我们返回的数据===>{}",respBody);
        //解析 银行返回的数据
        // {"respData":{"respCode":"00000","respMsg":"成功","status":1,"requestNo":"REQ_208f14ff-b"}}
        BankRespDto bankRespDto = JSON.parseObject(respBody, BankRespDto.class);
        //拿到 respData 数据: {"respCode":"00000","respMsg":"成功","status":1,"requestNo":"REQ_208f14ff-b"}
        String respData = bankRespDto.getRespData();
        BaseResult baseResult = JSON.parseObject(respData, BaseResult.class);

        //发送数据到银行系统
        if (baseResult.getRespMsg().equals("成功")){
            //更新 tradelog
            update(
                    Wrappers.lambdaUpdate(TradeLog.class)
                            .set(TradeLog::getSynchronizeStatus,1)
                            .set(TradeLog::getConfirmDate,new Date())
                            .set(TradeLog::getResponseData,respData)
                            .eq(TradeLog::getId,tradeLog.getId())
            );
            return baseResult;
        }
        return null;
    }
}
